<template>
  <div class="add-review-page">
    <div class="container">
      <el-card class="review-card">
        <template #header>
          <div class="card-header">
            <h2>添加评论 - {{ hotelName }}</h2>
            <div class="booking-info">
              房型: {{ roomType }} | 订单号: {{ bookingId }}
            </div>
          </div>
        </template>

        <el-form :model="reviewForm" :rules="rules" ref="reviewFormRef" label-position="top">
          <el-form-item label="您的评分" prop="rating">
            <el-rate
              v-model="reviewForm.rating"
              allow-half
              :colors="['#FF9900', '#FF9900', '#FF9900']"
              :show-score="true"
              score-template="{value}"
              size="large"
            />
          </el-form-item>

          <el-form-item label="评论内容" prop="content">
            <el-input
              type="textarea"
              v-model="reviewForm.content"
              :rows="5"
              placeholder="请分享您的住宿体验，帮助其他旅客做出更好的选择..."
              maxlength="500"
              show-word-limit
            />
          </el-form-item>

          <el-form-item label="上传照片（可选）">
            <el-upload
              v-model:file-list="fileList"
              action=""
              list-type="picture-card"
              :limit="5"
              :auto-upload="true"
              :on-preview="handlePictureCardPreview"
              :on-remove="handleRemove"
              :before-upload="beforeUpload"
              :http-request="customUpload"
            >
              <el-icon><Plus /></el-icon>
            </el-upload>
            <el-dialog v-model="previewVisible">
              <img w-full :src="previewImage" alt="Preview Image" />
            </el-dialog>
          </el-form-item>

          <el-form-item>
            <div class="form-actions">
              <el-button @click="goBack">取消</el-button>
              <el-button type="primary" @click="submitReview" :loading="submitting">提交评论</el-button>
            </div>
          </el-form-item>
        </el-form>
      </el-card>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import type { FormInstance, UploadProps, UploadUserFile, UploadRequestOptions } from 'element-plus';
import { Plus } from '@element-plus/icons-vue';
import { apiAddReview, apiUploadReviewImage } from '@/api/api';
import type { AxiosResponse } from 'axios';

interface ApiResponse {
  code: number;
  msg?: string;
  data?: any;
}

const route = useRoute();
const router = useRouter();
const reviewFormRef = ref<FormInstance>();
const submitting = ref(false);

// 从路由参数中获取信息
const bookingId = ref(route.params.bookingId as string);
const hotelId = ref(route.params.hotelId as string);
const hotelName = ref(route.query.hotel as string || '');
const roomType = ref(route.query.roomType as string || '');

// 表单数据
const reviewForm = reactive({
  rating: 5,
  content: '',
});

// 表单验证规则
const rules = {
  rating: [
    { required: true, message: '请选择评分', trigger: 'change' },
    { type: 'number', min: 1, message: '评分不能低于1', trigger: 'change' }
  ],
  content: [
    { required: true, message: '请输入评论内容', trigger: 'blur' },
    { min: 5, message: '评论内容不能少于5个字符', trigger: 'blur' }
  ]
};

// 图片上传相关
const fileList = ref<UploadUserFile[]>([]);
const previewVisible = ref(false);
const previewImage = ref('');
const uploadedUrls = ref<string[]>([]); // 用于跟踪已上传的URL

// 预览图片
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  previewImage.value = uploadFile.url!;
  previewVisible.value = true;
};

// 删除图片时也从URL列表中移除
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  if (uploadFile.url) {
    const index = uploadedUrls.value.indexOf(uploadFile.url);
    if (index !== -1) {
      uploadedUrls.value.splice(index, 1);
    }
  }
};

// 上传前检查
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
  const isImage = file.type.startsWith('image/');
  const isLt2M = file.size / 1024 / 1024 < 2;

  if (!isImage) {
    ElMessage.error('只能上传图片文件!');
    return false;
  }
  
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过2MB!');
    return false;
  }
  
  return true;
};

// 自定义上传处理
const customUpload = async (options: UploadRequestOptions) => {
  const { file, onSuccess, onError } = options;
  
  // 创建表单数据
  const formData = new FormData();
  formData.append('file', file);
  
  try {
    // 显示上传中状态
    ElMessage.info('正在上传图片...');
    
    // 上传图片到阿里云OSS
    const res = await apiUploadReviewImage(formData);
    
    if (res.code === 200 && res.data) {
      // 上传成功，将返回的阿里云URL添加到图片列表
      const imageUrl = res.data;
      
      // 检查URL是否已存在于列表中，避免重复
      if (!uploadedUrls.value.includes(imageUrl)) {
        // 添加到已上传URL列表
        uploadedUrls.value.push(imageUrl);
        
        // 创建上传文件对象，注意类型匹配
        const uploadedFile = {
          name: file.name,
          url: imageUrl,
          uid: Date.now(), // UID应为数字类型
          status: 'success' as const // 明确状态
        };
        
        // 调用成功回调
        if (onSuccess) {
          onSuccess(uploadedFile);
        }
        
        ElMessage.success('图片上传成功');
      } else {
        ElMessage.warning('该图片已上传');
        
        // 调用错误回调，以便元素组件知道不要显示这张图片
        if (onError) {
          const ajaxError = {
            name: 'UploadError',
            message: '图片已存在',
            status: 400,
            method: 'post',
            url: ''
          };
          onError(ajaxError);
        }
      }
    } else {
      // 创建自定义错误对象
      const errorObj = {
        name: 'UploadError',
        message: res.msg || '图片上传失败',
        status: 400,
        method: 'post',
        url: ''
      };
      
      if (onError) {
        onError(errorObj);
      }
      ElMessage.error(res.msg || '图片上传失败');
    }
  } catch (error) {
    console.error('上传图片失败:', error);
    
    // 创建自定义错误对象
    const errorObj = {
      name: 'UploadError',
      message: '图片上传失败',
      status: 500,
      method: 'post',
      url: ''
    };
    
    if (onError) {
      onError(errorObj);
    }
    ElMessage.error('图片上传失败，请稍后重试');
  }
};

// 返回上一页
const goBack = () => {
  router.back();
};

// 提交评论
const submitReview = async () => {
  if (!reviewFormRef.value) return;
  
  const valid = await reviewFormRef.value.validate()
    .then(() => true)
    .catch(() => false);
    
  if (valid) {
    submitting.value = true;
    
    try {
      // 使用跟踪的URL列表而不是从fileList提取，避免重复
      const imageUrls = uploadedUrls.value;
      
      // 准备评论数据
      const reviewData = {
        hotelId: hotelId.value,
        bookingId: parseInt(bookingId.value),
        rating: reviewForm.rating,
        content: reviewForm.content,
        images: imageUrls,
        roomType: roomType.value
      };
      
      // 调用API提交评论
      const res = await apiAddReview(reviewData) as unknown as ApiResponse;
      
      if (res.code === 200) {
        ElMessage.success('评论提交成功！');
        // 返回到订单页面
        router.push('/profile?tab=orders');
      } else {
        ElMessage.error(res.msg || '评论提交失败');
      }
    } catch (error) {
      console.error('提交评论失败:', error);
      ElMessage.error('评论提交失败，请稍后重试');
    } finally {
      submitting.value = false;
    }
  } else {
    ElMessage.warning('请完成必填信息');
  }
};

// 页面加载时检查参数
onMounted(() => {
  if (!bookingId.value || !hotelId.value) {
    ElMessage.error('缺少必要参数');
    router.push('/profile?tab=orders');
  }
});
</script>

<style scoped>
.add-review-page {
  padding: 40px 0;
  background-color: #f5f7fa;
  min-height: calc(100vh - 64px);
}

.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 0 20px;
}

.review-card {
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.card-header {
  display: flex;
  flex-direction: column;
}

.card-header h2 {
  margin: 0 0 8px 0;
  font-size: 20px;
  color: #2c3e50;
}

.booking-info {
  font-size: 14px;
  color: #606266;
}

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 20px;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .add-review-page {
    padding: 20px 0;
  }
}
</style> 